﻿//
//
/////////////////////////////////////////////////////////////////////////////
using System;
using System.Linq;
using System.Threading;
using FreeSpace.Logic.Data;
using FreeSpaceLibrary.Objects;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

/////////////////////////////////////////////////////////////////////////////
namespace FreeSpace.Logic
{
    /////////////////////////////////////////////////////////////////////////
    public class AsteroidField
    {
        private Rectangle _workField;
        private Asteroid[] _objects;
        private ContentManager _content;
        private SpriteBatch _sprite;
        private AsteroidFieldControl _parentControl;
        private object _locker = new object();
        private float _scale = 0.0f;
        private int _velocity = 100;
        private DataAsteroidField _data;

        /////////////////////////////////////////////////////////////////////
        public AsteroidField(int width, int height, ContentManager content, SpriteBatch sprite)
        {
            _scale = 1.0f;
            _workField = new Rectangle(0, 0, width, height);
            _content = content;
            _sprite = sprite;
        }

        /////////////////////////////////////////////////////////////////////
        public AsteroidField(int width, int height, ContentManager content, SpriteBatch sprite, float scale, int particleCount, int velocity)
        {
            if (particleCount <= 0)
            {
                throw new Exception("The particle count is wrong");
            }
            
            _scale = scale;
            _workField = new Rectangle(0, 0, width, height);
            _content = content;
            _sprite = sprite;
            _objects = new Asteroid[particleCount];
            _velocity = velocity;
        }

        /////////////////////////////////////////////////////////////////////
        public float Scale
        {
            get { return _scale; }
            set { _scale = value; }
        }

        /////////////////////////////////////////////////////////////////////
        public int Velocity
        {
            get { return _velocity; }
            set { _velocity = value; }
        }

        /////////////////////////////////////////////////////////////////////
        public void InitField()
        {
            if (_objects != null && _objects.Length > 0)
            {
                _data = new DataAsteroidField();
                _data.Generate(_objects.Length, _workField.Width, _workField.Height);

                for (int i = 0; i < _objects.Length; i++)
                {
                    _objects[i] = new Asteroid(_data.Positions[i], _content, Scale) { Velocity = _velocity };
                }
            }
        }

        /////////////////////////////////////////////////////////////////////
        public void Draw()
        {
            lock (_locker)
            {
                for (int i = 0; i < _objects.Length; i++)
                {
                    _objects[i].Draw(_sprite);
                } 
            }
        }

        /////////////////////////////////////////////////////////////////////
        public void StepY(float deltaTime)
        {
            for (int i = 0; i < _objects.Length; i++)
            {
                Vector2 position = _objects[i].Position;
                position.Y = _objects[i].Position.Y + _objects[i].Velocity * deltaTime / 1000.0f;
                _objects[i].Position = position;

                //Point position = _objects[i].Position;
                //position.Y = _objects[i].Position.Y + Convert.ToInt32(_objects[i].Velocity * deltaTime / 1000.0f);
                //_objects[i].Position = position;
            }
        }

        /////////////////////////////////////////////////////////////////////
        public void CheckBounds(GameTime totalGameTime)
        {
            for (int i = 0; i < _objects.Length; i++)
            {
                Vector2 position = _objects[i].Position;
                if (position.X > _workField.Width || position.Y > _workField.Height)
                {
                    Random random = new Random(totalGameTime.TotalGameTime.Milliseconds);
                    position.X = random.Next(0, _workField.Width);
                    position.Y = -2 * _objects[i].Radius;
                    _objects[i].Position = position;
                }

                //Point position = _objects[i].Position;
                //if (position.X > _workField.Width || position.Y > _workField.Height)
                //{
                //    Random random = new Random(totalGameTime.TotalGameTime.Milliseconds);
                //    position.X = random.Next(0, _workField.Width);
                //    position.Y = Convert.ToInt32(-2 * _objects[i].Radius);
                //    _objects[i].Position = position;
                //}
            }
        }

        /////////////////////////////////////////////////////////////////////
        public void InitParentControl(AsteroidFieldControl parentControl)
        {
            _parentControl = parentControl;
            _parentControl.DrawField += new AsteroidFieldControl.Draw(ParentControlDrawField);
            _parentControl.UpdateField += new AsteroidFieldControl.Update(ParentControlUpdateField);
        }

        /////////////////////////////////////////////////////////////////////
        private void ParentControlDrawField()
        {
            Draw();
        }

        /////////////////////////////////////////////////////////////////////
        private void ParentControlUpdateField(GameTime gameTime)
        {
            this.StepY((float)gameTime.ElapsedGameTime.TotalMilliseconds);
            this.CheckBounds(gameTime);
        }
    }
/////////////////////////////////////////////////////////////////////////////
}//FreeSpace.Logic
